#include <iostream>
#include <memory>



/* 工厂1: 违反了开闭原则 */

// class FruitFartory
// {
// public:
//     static std::shared_ptr<Fruit> create(const std::string &name)
//     {
//         if(name == "苹果")
//         {
//             return std::make_shared<Apple>();
//         }
//         else
//         {
//             return std::make_shared<Banana>();
//         }
//     }
// private:
// };

/* 工厂2: 利用继承来拆分工厂，使一个产品一个工厂 */
// class FruitFartory
// {
// public:
//     virtual std::shared_ptr<Fruit> create() = 0;
// };

// class AppleFartory : public FruitFartory
// {
// public:
//     std::shared_ptr<Fruit> create() override
//     {
//         return std::make_shared<Apple>();
//     }
// };

// class BananaFartory : public FruitFartory
// {
// public:
//     std::shared_ptr<Fruit> create() override
//     {
//         return std::make_shared<Banana>();
//     }
// };

class Fruit
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    void name() override
    {
        std::cout << "Apple" << std::endl;
    }
};

class Banana : public Fruit
{
public:
    void name() override
    {
        std::cout << "Banana" << std::endl;
    }
};

class Animal
{
public:
    virtual void name() = 0;
};

class Lamp : public Animal
{
public:
    void name() override
    {
        std::cout << "山羊" << std::endl;
    }
};

class Dog : public Animal
{
public:
    void name() override
    {
        std::cout << "土狗" << std::endl;
    }
};

/* 工厂3: 超级工厂 */

class Factory
{
public:
    virtual std::shared_ptr<Fruit> getfruit(const std::string &name) = 0;
    virtual std::shared_ptr<Animal> getanimal(const std::string &name) = 0;
};

class FruitFactory : public Factory
{
public:
    std::shared_ptr<Animal> getanimal(const std::string &name) override
    {
        return std::shared_ptr<Animal>();
    }

    std::shared_ptr<Fruit> getfruit(const std::string &name) override
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else
        {
            return std::make_shared<Banana>();
        }
    }
};

class AnimalFactory : public Factory
{
public:
    std::shared_ptr<Fruit> getfruit(const std::string &name) override
    {
        return std::shared_ptr<Fruit>();
    }

    std::shared_ptr<Animal> getanimal(const std::string &name) override
    {
        if(name == "山羊")
        {
            return std::make_shared<Lamp>();
        }
        else
        {
            return std::make_shared<Dog>();
        }
    }
};

class FactoryProducer
{
public:
    static std::shared_ptr<Factory> create(const std::string &name)
    {
        if(name == "水果")
        {
            return std::make_shared<FruitFactory>();
        }
        else
        {
            return std::make_shared<AnimalFactory>();
        }
    }
};

int main()
{
    // std::shared_ptr<Fruit> fruit = std::make_shared<Apple>();
    // fruit->name();
    // fruit = FruitFartory::create("香蕉");

    //BananaFartory banana;
    // fruit = banana.create();
    // fruit->name();

    std::shared_ptr<Factory> ff = FactoryProducer::create("水果");
    std::shared_ptr<Fruit> fruit = ff->getfruit("苹果");
    fruit->name();
    fruit = ff->getfruit("香蕉");
    fruit->name();

    return 0;
}